
/**
 * 重写window的onError事件
 * 
 * @param {}
 *            msg 错误信息
 * @param {}
 *            fileName 文件名
 * @param {}
 *            rowIndex 行数
 * @return {Boolean}
 */
window.onerror = function(msg, fileName, rowIndex) {
	if (Aby) {
		if (Aby.showErrorMessage || Aby.showErrorMsg) {
			Aby.util.error("在文件" + fileName + "里的第" + rowIndex + "行发生了" + msg
							+ "的错误！", Aby.jsErrorCallBack, "脚本错误");
			return Aby.clearError;
		}
		if (Aby.clearError) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
};


/*
 * 重写或扩展Ext的代码
 * ***************************************************************************
 */

/**
 * Ext里的弹出框
 * 
 * @type
 */
Aby.util.error = function(msg, fn, title) {
	Ext.MessageBox.show({
				title : title ? title : '错误',
				icon : Ext.MessageBox.ERROR,
				buttons : Ext.MessageBox.OK,
				width : (msg.length * 12 + 90) > 500
						? 500
						: (msg.length * 12 + 90),
				msg : msg,
				fn : fn
			});
};
Aby.util.info = function(msg, fn, title) {
	Ext.MessageBox.show({
				title : title ? title : '提示',
				icon : Ext.MessageBox.INFO,
				buttons : Ext.MessageBox.OK,
				msg : msg,
				width : (msg.length * 12 + 90) > 500
						? 500
						: (msg.length * 12 + 90),
				fn : fn
			});
};
Aby.util.warn = function(msg, fn, title) {
	Ext.MessageBox.show({
				title : title ? title : '警告',
				icon : Ext.MessageBox.WARNING,
				buttons : Ext.MessageBox.OK,
				msg : msg,
				width : (msg.length * 12 + 90) > 500
						? 500
						: (msg.length * 12 + 90),
				fn : fn
			});
};
Aby.util.confirm = function(msg, fn, title) {
	Ext.MessageBox.show({
				title : title ? title : '确认',
				icon : Ext.MessageBox.QUESTION,
				buttons : Ext.MessageBox.YESNO,
				msg : msg,
				width : (msg.length * 12 + 90) > 500
						? 500
						: (msg.length * 12 + 90),
				fn : fn
			});
},
Aby.util.ajaxFailure = function(action, fn) {
	switch (action.failureType) {
		case Ext.form.Action.CLIENT_INVALID :
			Aby.util.error("数据提交失败！");
			break;
		case Ext.form.Action.CONNECT_FAILURE :
			Aby.util.error("Ajax与服务器通信失败！");
			break;
		case Ext.form.Action.SERVER_INVALID :
			Aby.util.error("程序出错！");
	}
};
Aby.util.fckArea = function(id, width, height) {

	var sBasePath = "/fckeditor/";
	var oFCKeditor = new FCKeditor(id);
	oFCKeditor.BasePath = sBasePath;
	oFCKeditor.Width = '90%';
	oFCKeditor.Height = height;
	oFCKeditor.ReplaceTextarea();
	return oFCKeditor;
};
Aby.util.ajax = function(classname, methodname, success, failure, params, arg){
	var p = {};
	if(!params)
		params ={};
	Ext.apply(p,params);
	Ext.apply(p,{
		classname:classname,
	 	methodname:methodname
	});
	var config = {
		url : Aby.os.url,
		params : p
	};
	if(Aby.isFunction(success))
		config["success"] = success;
	if(!Aby.isFunction(failure))
		failure = function(response, opts){
			var json = Ext.decode(response.responseText);
			Aby.util.error(json.message);
			return;
		};
	config["failure"] = failure;
	Ext.apply(config, arg);
	Ext.Ajax.request(config);
}


/**
 * window的拖放，修改遇到iframe卡主住的bug
 * 
 * @param {Object}
 *            e
 */
//Ext.override(Ext.Window.DD, {
//	onDrag : function(e) {
//		// code
//		this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
//	},
//	endDrag : function(e) {
//		this.win.unghost();
//		this.win.saveState();
//		// code
//	}
//});

Ext.isEmptyObj = function(obj){
	var f = true;
	if(obj != null && typeof obj == "object"){
		for(var p in obj){
			f = false;
		}		
	}else{
		f = true;
	}	
	return f;
}

/**
 * 扩展Ext.tree.TreePanel 获得展开是树节点是id
 * 
 * @return ID的数组
 */
Ext.tree.TreePanel.prototype.getExpandedNodesId = function() {
	var rel = new Array();
	var nodes = this.root.childNodes
	if (nodes) {
		for (var i = 0; i < nodes.length; i++) {
			if (nodes[i].isExpanded())
				rel.push(nodes[i].id);
		}
	}
	return rel;
};

Ext.form.CompositeField.prototype.getFieldLabelByName = function(name) {
    var items = this.items.items;
    var target = null;
    items.each(function(item) {
        if (item.name == name)
            target = item.fieldLabel;
        return false;
    });
    return target;
}

/**
 * 扩展Ext.form.FormPanel的submit方法
 * 
 * @return {}
 */
Ext.form.FormPanel.prototype.submit = function() {  
	if (!this.form.isValid(true))
		this.validateItems();
	else
		return this.form.submit.apply(this.form, arguments)
};

/**
 * 扩展form验证
 */
Ext.form.FormPanel.prototype.validateItems = function() {
    try {
        var items = this.items.items;
        var blanks = "";
        var errorFields = [];
        for (var i = 0; i < items.length; i++) {
            if (items[i].isValid && !items[i].isValid(true)) {
                if (items[i].markInvalid) {
                    items[i].markInvalid();
                    if (items[i].fieldErrors) {
                        items[i].fieldErrors.each(function(e) {
                            var m =  items[i].getFieldLabelByName(e.field)+e.error+ "<br/>";
                            items[i].markInvalid(m);
                            blanks += m;
                        });
                    } else {
                        if (items[i].allowBlank === false && !items[i].getValue()) {
                            items[i].blankText = items[i].fieldLabel + "不能为空！";
                            blanks += (items[i].blankText + "<br/>");
                            errorFields.push(items[i]);
                            continue;
                        } else {
                            if (items[i].activeError) {
                                blanks += items[i].vtypeText || items[i].regexText + "<br/>";
                                errorFields.push(items[i]);
                            }
                        }
                    }
                }
            }
        }
        Ext.Msg.show({
            title: '验证信息',
            icon: Ext.MessageBox.ERROR,
            buttons: Ext.MessageBox.OK,
            width: 350,
            msg: blanks.toString(),
            fn: function() {
                for (var i = 0; i < errorFields.length; i++) {
                    errorFields[i].reset();
                }
                if (errorFields[0])
                    errorFields[0].selectText();
                errorFields = null;
                return;
            }
        });
    } finally {
        blanks = null;
        items = null;
    }
};
Ext.form.BasicForm.prototype.validateItems = Ext.form.FormPanel.prototype.validateItems;


/**
 * 重写验证方法
 * 
 * @param {}
 *            value
 * @return {Boolean}
 */
Ext.form.FormPanel.prototype.validateItems = function() {
	try {
		var items = this.items.items;
		var blanks = "";
		var errorFields = [];

		for (var i = 0; i < items.length; i++) {
			var item = items[i];
			if (!item.isValid(true)) {
				if (item.getValue() == "") {
					if (!item.allowBlank) {
						if (item.blankText.indexOf("This is") == -1) {
							item.blankText = item.fieldLabel + "不能为空！";
						}
						blanks += item.blankText + "<br/>";
						errorFields.push(item);
						continue;
					}
				} else {
					if (item.vtype) {
						var vt = Ext.form.VTypes;
						if (!vt[item.vtype](item.value, item)) {
							item.markInvalid(item.vtypeText
									|| vt[item.vtype + 'Text']);
							blanks += item.vtypeText || vt[item.vtype + 'Text']
									+ "<br/>";
							errorFields.push(item);
							continue;
						}
					} else {

						if (item.regex && !item.regex.test(item.value)) {
							blanks += item.regexText + "<br/>";
							errorFields.push(item);
							continue;
						}
					}
				}
			}
		}
		blanks = blanks.substr(0, blanks.length - 5);
		if (blanks)
			Ext.Msg.show({
						title : '验证信息',
						icon : Ext.MessageBox.ERROR,
						buttons : Ext.MessageBox.OK,
						width : 350,
						msg : blanks.toString().replace(/[ ]/g, ""),
						fn : function() {
							for (var i = 0; i < errorFields.length; i++) {
								errorFields[i].reset();
							}
							if (errorFields && errorFields[0])
								errorFields[0].selectText();
							errorFields = null;
							return;
						}
					});
	} finally {
		blanks = null;
		items = null;
	}
};
Ext.form.BasicForm.prototype.validateItems = Ext.form.FormPanel.prototype.validateItems;



/**
 * 扩展VTypes的多次输入的数据是否一致
 */
Ext.apply(Ext.form.VTypes, {

	password : function(val, field) {
		if (field.passField) {
			var pwd = Ext.getCmp(field.passField);
			return (val == pwd.getValue());
		}
		return true;
	},
	passwordText : '两次输入的密码不一致!'
});

/**
 * 有checkbox的下拉框树
 * 
 * @class Aby.ui.ComboCheckTree
 * @extends Ext.form.ComboBox
 */
Aby.ui.ComboCheckTree = Ext.extend(Ext.form.ComboBox, {
			tree : null,
			treeRenderID : null,
			text : new Array(),
			vl : new Array(),
			constructor : function(cfg) {
				Ext.apply(this, cfg);
				this.treeRenderID = cfg.id == null
						? Ext.id + "-comboTree"
						: cfg.id + "-comboTree";
				this.tree = cfg.tree;
				Aby.ui.ComboCheckTree.superclass.constructor.call(this, {
							store : new Ext.data.SimpleStore({
										fields : [],
										data : [[]]
									}),
							onSelect : Ext.emptyFn,
							editable : false,
							forceSelection : true,
							mode : 'local',
							triggerAction : 'all',
							typeAhead : true,
							typeAheadDelay : 100,
							tree : this.tree,
							tpl : "<tpl for='.'><div style='height:200px' id='"
									+ this.treeRenderID +

									"'></div></tpl>"
						});
			},
			expand : function() {
				Aby.ui.ComboCheckTree.superclass.expand.call(this)
				if (this.tree != null) {
					this.tree.expand(true);
					this.tree.on('checkchange', function(node, check) {
								var isRoot = (node == this.tree.getRootNode());
								var selModel = this.selectNodeModel;
								var isLeaf = node.isLeaf();
								if (selModel == 'folder' && isLeaf) {
									return;
								} else if (selModel == 'leaf' && !isLeaf) {
									return;
								}
								if (check) {
									this.text.push(node.text);
									this.vl.push(node.id);
								} else {
									this.text.remove(node.text);
									this.vl.remove(node.id);
								}
								this.value = this.vl.toString();
								this.setValue(this.text.toString());
							}, this);
					this.on("collapse", function() {
								this.collapse();
							})
					this.tree.getRootNode().expand(true);
					this.tree.render(this.treeRenderID);
				}

			},
			getValue : function() {
				return this.value;
			},
			getText : function() {
				return this.text;
			}
		});

/**
 * 没有checkbox的下拉框树
 * 
 * @class Aby.ui.ComboTree
 * @extends Ext.form.ComboBox
 */
Aby.ui.ComboTree = Ext.extend(Ext.form.ComboBox, {
			tree : null,
			treeRenderID : null,
			text : null,
			constructor : function(cfg) {
				Ext.apply(this, cfg);
				this.treeRenderID = cfg.id == null
						? Ext.id + "-comboTree"
						: cfg.id + "-comboTree";
				this.tree = cfg.tree;
				Aby.ui.ComboTree.superclass.constructor.call(this, {
							store : new Ext.data.SimpleStore({
										fields : [],
										data : [[]]
									}),
							onSelect : Ext.emptyFn,
							editable : false,
							forceSelection : true,
							mode : 'local',
							triggerAction : 'all',
							typeAhead : true,
							typeAheadDelay : 100,
							tree : this.tree,
							value : this.value,
							emptyText : this.text,
							tpl : "<tpl for='.'><div style='height:200px' id='"
									+ this.treeRenderID +

									"'></div></tpl>"
						});
			},
			expand : function() {
				Aby.ui.ComboTree.superclass.expand.call(this)
				if (this.tree != null) {
					this.tree.expand(true);
					this.tree.on('click', function(node) {
								var isRoot = (node == this.tree.getRootNode());
								var selModel = this.selectNodeModel;
								var isLeaf = node.isLeaf();
								if (selModel == 'folder' && isLeaf) {
									return;
								} else if (selModel == 'leaf' && !isLeaf) {
									return;
								}
								this.setValue(node.text);
								this.text = node.text;
								this.value = node.id;
								Ext.get(this.hiddenName).dom.value = this.value;
								this.collapse();
							}, this);

					this.tree.render(this.treeRenderID);
				}
			},
			getValue : function() {
				return this.value;
			},
			getText : function() {
				return this.text;
			}
		});

/**
 * 创建form
 * 
 * @param {}
 *            cfg 运行为空的写在blankFields（可空字段的id或name）里，可以在items里写入原生的表单元素
 * @return {Ext.form.FormPanel}实例
 */
Ext.form.CreateForm = function(cfg) {
	var items = [];
	var label = cfg.LabelConfig;
	if (cfg) {
		cfg.items.each(function(v) {
					if (typeof v == "string") {
						if (cfg.blankFields) {
							for (var i = 0; i < cfg.blankFields.length; i++) {
								if (v == cfg.blankFields[i]) {
									items.push({
												fieldLabel : label[v],
												name : v,
												id : v,
												allowBlank : true
											});
									break;
								} else {
									items.push({
												fieldLabel : label[v],
												name : v,
												id : v
											});
								}
							}
						} else {
							items.push({
										fieldLabel : label[v],
										name : v,
										id : v
									});
						}
					} else {
						items.push(v);
					}
				});
	}
	var config = {
		items : items
	};
	if (!cfg.defaults)
		cfg.defaults = {};
	Ext.applyIf(cfg.defaults, {
				xtype : 'textfield'
			});
	Ext.applyIf(cfg, {
				labelWidth : 80,
				labelAlign : 'right',
				frame : true
			});
	Ext.applyIf(config, cfg);
	return new Ext.form.FormPanel(config);
};

/**
 * 重写Ext.form.TextField的验证方法
 * 
 * @param {}
 *            value
 * @return {Boolean}
 */
Ext.form.TextField.prototype.validateValue = function(value) {
	if (Ext.isFunction(this.validator)) {
		var msg = this.validator(value);
		if (msg !== true) {
			this.markInvalid(msg);
			return false;
		}
	}
	if (value.length < 1 || value === this.emptyText) {
		if (this.allowBlank) {
			this.clearInvalid();
			return true;
		} else {
			if (this.blankText.length == 5)
				this.markInvalid(this.fieldLabel + this.blankText);
			else
				this.markInvalid(this.blankText);
			return false;
		}
	}
	if (value.length < this.minLength) {
		this.markInvalid(String.format(this.minLengthText, this.minLength));
		return false;
	}
	if (value.length > this.maxLength) {
		this.markInvalid(String.format(this.maxLengthText, this.maxLength));
		return false;
	}
	if (this.vtype) {
		var vt = Ext.form.VTypes;
		if (!vt[this.vtype](value, this)) {
			this.markInvalid(this.vtypeText || vt[this.vtype + 'Text']);
			return false;
		}
	}
	if (this.regex && !this.regex.test(value)) {
		this.markInvalid(this.regexText);
		return false;
	}
	return true;
};

/**
 * 搜索框
 * 
 * @class Ext.ux.form.SearchField
 * @extends Ext.form.TwinTriggerField
 */
Ext.ns("Ext.ux.form");
Ext.ux.form.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
			initComponent : function() {
				Ext.ux.form.SearchField.superclass.initComponent.call(this);
				this.on('specialkey', function(f, e) {
							if (e.getKey() == e.ENTER) {
								this.onTrigger2Click();
							}
						}, this);
			},

			validationEvent : false,
			validateOnBlur : false,
			trigger1Class : 'x-form-clear-trigger',
			trigger2Class : 'x-form-search-trigger',
			hideTrigger1 : true,
			width : 180,
			hasSearch : false,
			paramName : 'search',

			onTrigger1Click : function() {
				if (this.hasSearch) {
					this.el.dom.value = '';
					var o = {
						start : 0,
						limit : 20
					};
					this.store.baseParams = this.store.baseParams || {};
					this.store.baseParams[this.paramName] = '';
					this.store.reload({
								params : o
							});
					this.triggers[0].hide();
					this.hasSearch = false;
				}
			},

			onTrigger2Click : function() {
				var v = this.getRawValue();
				if (v.length < 1) {
					this.onTrigger1Click();
					return;
				}
				var o = {
					start : 0,
					limit : 30
				};
				this.store.baseParams = this.store.baseParams || {};
				this.store.baseParams[this.paramName] = v;
				this.store.reload({
							params : o
						});
				this.hasSearch = true;
				this.triggers[0].show();
			}
		});


Ext.form.FileUploadField = Ext.extend(Ext.form.TextField, {
    /**
    * @cfg {String} buttonText The button text to display on the upload button (defaults to
    * 'Browse...').  Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text
    * value will be used instead if available.
    */
    buttonText: 'Browse...',
    /**
    * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible
    * text field (defaults to false).  If true, all inherited TextField members will still be available.
    */
    buttonOnly: false,
    /**
    * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field
    * (defaults to 3).  Note that this only applies if {@link #buttonOnly} = false.
    */
    buttonOffset: 3,
    /**
    * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object.
    */

    // private
    readOnly: true,

    /**
    * @hide
    * @method autoSize
    */
    autoSize: Ext.emptyFn,

    // private
    initComponent: function () {
        Ext.form.FileUploadField.superclass.initComponent.call(this);

        this.addEvents(
        /**
        * @event fileselected
        * Fires when the underlying file input field's value has changed from the user
        * selecting a new file from the system file selection dialog.
        * @param {Ext.form.FileUploadField} this
        * @param {String} value The file value returned by the underlying file input field
        */
            'fileselected'
        );
    },

    // private
    onRender: function (ct, position) {
        Ext.form.FileUploadField.superclass.onRender.call(this, ct, position);

        this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
        this.el.addClass('x-form-file-text');
        this.el.dom.removeAttribute('name');
        this.createFileInput();

        var btnCfg = Ext.applyIf(this.buttonCfg || {}, {text: this.buttonText});
        this.button = new Ext.Button(Ext.apply(btnCfg, {
            renderTo: this.wrap,
            cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : '')
        }));

        if (this.buttonOnly) {
            this.el.hide();
            this.wrap.setWidth(this.button.getEl().getWidth());
        }

        this.bindListeners();
        this.resizeEl = this.positionEl = this.wrap;
    },

    bindListeners: function () {
        this.fileInput.on({
            scope: this,
            mouseenter: function () {
                this.button.addClass(['x-btn-over', 'x-btn-focus'])
            },
            mouseleave: function () {
                this.button.removeClass(['x-btn-over', 'x-btn-focus', 'x-btn-click'])
            },
            mousedown: function () {
                this.button.addClass('x-btn-click')
            },
            mouseup: function () {
                this.button.removeClass(['x-btn-over', 'x-btn-focus', 'x-btn-click'])
            },
            change: function () {
                var v = this.fileInput.dom.value;
                this.setValue(v);
                this.fireEvent('fileselected', this, v);
            }
        });
    },

    createFileInput: function () {
        this.fileInput = this.wrap.createChild({
            id: this.getFileInputId(),
            name: this.name || this.getId(),
            cls: 'x-form-file',
            tag: 'input',
            type: 'file',
            size: 1
        });
    },

    reset: function () {
        this.fileInput.remove();
        this.createFileInput();
        this.bindListeners();
        Ext.form.FileUploadField.superclass.reset.call(this);
    },

    // private
    getFileInputId: function () {
        return this.id + '-file';
    },

    // private
    onResize: function (w, h) {
        Ext.form.FileUploadField.superclass.onResize.call(this, w, h);

        this.wrap.setWidth(w);

        if (!this.buttonOnly) {
            var w = this.wrap.getWidth() - this.button.getEl().getWidth() - this.buttonOffset;
            this.el.setWidth(w);
        }
    },

    // private
    onDestroy: function () {
        Ext.form.FileUploadField.superclass.onDestroy.call(this);
        Ext.destroy(this.fileInput, this.button, this.wrap);
    },

    onDisable: function () {
        Ext.form.FileUploadField.superclass.onDisable.call(this);
        this.doDisable(true);
    },

    onEnable: function () {
        Ext.form.FileUploadField.superclass.onEnable.call(this);
        this.doDisable(false);

    },

    // private
    doDisable: function (disabled) {
        this.fileInput.dom.disabled = disabled;
        this.button.setDisabled(disabled);
    },


    // private
    preFocus: Ext.emptyFn,

    // private
    alignErrorIcon: function () {
        this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
    }

});
Ext.reg('fileuploadfield', Ext.form.FileUploadField);
Ext.reg('filefield', Ext.form.FileUploadField);

/**
 * 行布局
 * 
 * @class Ext.ux.RowLayout
 * @extends Ext.layout.ContainerLayout
 */
Ext.ux.RowLayout = Ext.extend(Ext.layout.ContainerLayout, {
	monitorResize : true,
	scrollOffset : 0,
	margin : 0,
	split : false,
	isValidParent : function(c, target) {
		return c.getEl().dom.parentNode == this.innerCt.dom;
	},
	renderAll : function(ct, target) {
		if (this.split && !this.splitBars) {
			this.splitBars = [];
			this.margin = 5;
		}
		Ext.ux.RowLayout.superclass.renderAll.apply(this, arguments);
	},
	onLayout : function(ct, target) {
		var cs = ct.items.items, len = cs.length, c, cel, i;
		if (!this.innerCt) {
			target.addClass("x-column-layout-ct");
			this.innerCt = target.createChild({
						cls : "x-column-inner"
					});
			this.innerCt.createChild({
						cls : "x-clear"
					});
		}
		this.renderAll(ct, this.innerCt);
		var size = Ext.isIE
				&& ((target.dom != Ext.getBody().dom) && (target.dom != document.forms

				[0])) ? target.getStyleSize() : target.getViewSize();
		if (size.height < 1 && size.height < 1) {
			return;
		}
		var w = size.height - target.getPadding("tb");
		this.availableHeight = w;
		var pw = this.availableHeight, lastProportionedColumn;
		if (this.split) {
			this.minHeight = Math.min(pw / len, 100);
			this.maxHeight = pw
					- ((this.minHeight + 5) * (len ? (len - 1) : 1));
		}
		this.innerCt.setHeight(w);
		for (i = 0; i < len; i++) {
			c = cs[i];
			cel = c.getEl();
			if (this.margin && (i < (len - 1))) {
				cel.setStyle("margin-bottom", this.margin + "px");
			}
			if (c.rowHeight) {
				lastProportionedColumn = i;
			} else {
				pw -= (c.getSize().height + cel.getMargins("tb"));
			}
		}
		var remaining = (pw = pw < 0 ? 0 : pw), splitterPos = 0, cw;
		for (i = 0; i < len; i++) {
			c = cs[i];
			cel = c.getEl();
			if (c.rowHeight) {
				cw = (i == lastProportionedColumn) ? remaining : Math
						.floor(c.rowHeight *

						pw);
				c.setHeight(cw - cel.getMargins("tb"));
				if (Ext.isEmpty(c.width)) {
					var elWidth = size.width - target.getPadding("lr") -

					this.scrollOffset;
					c.setWidth(elWidth);
				}
				remaining -= cw;
			} else if (Ext.isEmpty(c.width)) {
				c.setWidth(size.width - target.getPadding("lr")
						- this.scrollOffset);
			}
			if (this.split) {
				cw = cel.getHeight();
				if (i < (len - 1)) {
					splitterPos += cw;
					this.splitBars[i] = new Ext.SplitBar(
							this.innerCt.createChild({
										cls : "x-layout-split x-layout-split-north",
										style : {
											left : "0px",
											top : splitterPos + "px",
											width : "100%",
											height : this.margin + "px"
										}
									}), cel, Ext.SplitBar.VERTICAL,
							Ext.SplitBar.TOP);
					this.splitBars[i].index = i;
					this.splitBars[i].topComponent = c;
					this.splitBars[i].addListener("resize",
							this.onColumnResize, this);
					this.splitBars[i].minSize = this.minHeight;
					splitterPos += this.splitBars[i].el.getHeight();
				}
				delete c.rowHeight;
			}
		}
		if (this.split) {
			this.setMaxHeights();
		}
	},
	onColumnResize : function(sb, newHeight) {
		if (sb.dragSpecs.startSize) {
			sb.topComponent.el.setStyle("height", "");
			sb.topComponent.setHeight(newHeight);
			var items = this.container.items.items, expansion = newHeight -

			sb.dragSpecs.startSize;
			for (var i = sb.index + 1, len = items.length; expansion && i < len; i++) {
				var c = items[i], w = c.el.getHeight();
				newHeight = w - expansion;
				if (newHeight < this.minHeight) {
					c.setHeight(this.minHeight);
				} else if (newHeight > this.maxHeight) {
					expansion -= (newHeight - this.maxHeight);
					c.setHeight(this.maxHeight);
				} else {
					c.setHeight(c.el.getHeight() - expansion);
					break;
				}
			}
			this.setMaxHeights();
		}
	},
	setMaxHeights : function() {
		var items = this.container.items.items, spare = items[items.length - 1].el.dom.offsetHeight
				-

				100, i;
		for (i = items.length - 2; i > -1; i--) {
			var sb = this.splitBars[i], sbel = sb.el, c = items[i], cel = c.el, itemHeight =

			cel.dom.offsetHeight;
			sbel.setStyle("top", (cel.getY()
							- Ext.fly(cel.dom.parentNode).getY() + itemHeight)
							+

							"px");
			sb.maxSize = itemHeight + spare;
			spare = itemHeight - 100;
		}
	},
	onResize : function() {
		if (this.split) {
			var items = this.container.items.items, tw = 0, c, i;
			if (items[0].rendered) {
				for (i = 0; i < items.length; i++) {
					c = items[i];
					tw += c.el.getHeight() + c.el.getMargins("tb");
				}
				for (i = 0; i < items.length; i++) {
					c = items[i];
					c.rowHeight = (c.el.getHeight() + c.el.getMargins("tb"))
							/ tw;
				}
			}
		}
		Ext.ux.RowLayout.superclass.onResize.apply(this, arguments);
	},
	renderItem : function(c) {
		Ext.ux.RowLayout.superclass.renderItem.apply(this, arguments);
		c.on("collapse", function() {
					this.layout();
				}, this);
		c.on("expand", function() {
					this.layout();
				}, this);
	}
});
Ext.Container.LAYOUTS["row"] = Ext.ux.RowLayout;

/**
 * 居中布局
 * 
 * @class Ext.ux.CenterLayout
 * @extends Ext.layout.FitLayout
 */
Ext.ux.CenterLayout = Ext.extend(Ext.layout.FitLayout, {
			setItemSize : function(item, size) {
				this.container.addClass('ux-layout-center');
				item.addClass('ux-layout-center-item');
				if (item && size.height > 0) {
					if (item.width) {
						size.width = item.width;
					}
					item.setSize(size);
				}
			}
		});
Ext.Container.LAYOUTS['center'] = Ext.ux.CenterLayout;

/**
 * 重写Ext.decode、Ext.util.JSON.doDecode方法 弥补json为字符串时的错误
 * 
 * @type
 */
Ext.decode = Ext.util.JSON.doDecode = function (json) {
    if (json.indexOf("TIMEOUT") > -1) {
        Aby.util.warn("会话过期，请重新登录！", function () { history.go(-1); });
    } else
        return eval("(" + json + ')');
};

Ext.override(Ext.PagingToolbar,{
	initComponent : function(){
		if(!this.displayInfo && this.displayInfo !== false)
			this.displayInfo = true;
		var T = Ext.Toolbar;
        var pagingItems = [this.first = new T.Button({
            tooltip: this.firstText,
            overflowText: this.firstText,
            iconCls: 'x-tbar-page-first',
            disabled: true,
            handler: this.moveFirst,
            scope: this
        }), this.prev = new T.Button({
            tooltip: this.prevText,
            overflowText: this.prevText,
            iconCls: 'x-tbar-page-prev',
            disabled: true,
            handler: this.movePrevious,
            scope: this
        }), '-', this.beforePageText,
        this.inputItem = new Ext.form.NumberField({
            cls: 'x-tbar-page-number',
            allowDecimals: false,
            allowNegative: false,
            enableKeyEvents: true,
            selectOnFocus: true,
            submitValue: false,
            listeners: {
                scope: this,
                keydown: this.onPagingKeyDown,
                blur: this.onPagingBlur
            }
        }), this.afterTextItem = new T.TextItem({
            text: String.format(this.afterPageText, 1)
        }), '-', this.next = new T.Button({
            tooltip: this.nextText,
            overflowText: this.nextText,
            iconCls: 'x-tbar-page-next',
            disabled: true,
            handler: this.moveNext,
            scope: this
        }), this.last = new T.Button({
            tooltip: this.lastText,
            overflowText: this.lastText,
            iconCls: 'x-tbar-page-last',
            disabled: true,
            handler: this.moveLast,
            scope: this
        }), '-', this.refresh = new T.Button({
            tooltip: this.refreshText,
            overflowText: this.refreshText,
            iconCls: 'x-tbar-loading',
            handler: this.doRefresh,
            scope: this
        })];


        var userItems = this.items || this.buttons || [];
        if (this.prependButtons) {
            this.items = userItems.concat(pagingItems);
        }else{
            this.items = pagingItems.concat(userItems);
        }
        
        this.items.push(this.middleItems || []);
        
        delete this.buttons;
        if(this.displayInfo){
            this.items.push('->');
            this.items.push(this.displayItem = new T.TextItem({}));
        }
        Ext.PagingToolbar.superclass.initComponent.call(this);
        this.addEvents(
            'change',
            'beforechange'
        );
        this.on('afterlayout', this.onFirstLayout, this, {single: true});
        this.cursor = 0;
        this.bindStore(this.store, true);
    }
 });

Aby.ActionBar = Ext.extend(Ext.Toolbar, {
    afterAction: true,
    enableOverflow: true,
    constructor: function (cfg, scope) {
        if (!cfg)
            cfg = {};
        Ext.apply(this, cfg);

        var btns = [];

        if (cfg.addHandler)
            btns.push({
                text: '新增',
                model: 'add',
                iconCls: 'aby-icon-add',
                handler: cfg.addHandler,
                scope: scope
            });
        if (cfg.modifyHandler)
            btns.push({
                text: '修改',
                model: 'edit',
                iconCls: 'aby-icon-edit',
                handler: cfg.modifyHandler,
                scope: scope
            });
        if (cfg.removeHandler)
            btns.push({
                text: '删除',
                model: 'delete',
                iconCls: 'aby-icon-delete',
                handler: cfg.removeHandler,
                scope: scope
            });

        if (cfg.refreshHandler) {
            btns.push("-");
            btns.push({
                text: '刷新',
                iconCls: 'aby-icon-refresh',
                handler: cfg.refreshHandler,
                scope: scope
            });
        }

        this.items = btns;

        if (cfg.items)
            if (this.afterAction)
                this.items.push(cfg.items);
            else {
                cfg.items.push(this.items);
                this.items = cfg.items;
            }
        Aby.ActionBar.superclass.constructor.call(this);
    }
});

Ext.ux.ActionBar = Aby.ActionBar;

Ext.form.HtmlEditor.override({
     enableFace: true,
     hideTools: false,
     enableUpload: true,
     createToolbar: function(editor) {
         var items = [];
         var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();


         function btn(id, toggle, handler) {
             return {
                 itemId: id,
                 cls: 'x-btn-icon',
                 iconCls: 'x-edit-' + id,
                 enableToggle: toggle !== false,
                 scope: editor,
                 handler: handler || editor.relayBtnCmd,
                 clickEvent: 'mousedown',
                 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
                 overflowText: editor.buttonTips[id].title || undefined,
                 tabIndex: -1
             };
         }


         if (this.enableFont && !Ext.isSafari2) {
             var fontSelectItem = new Ext.Toolbar.Item({
                 autoEl: {
                     tag: 'select',
                     cls: 'x-font-select',
                     html: this.createFontOptions()
                 }
             });

             items.push(
                fontSelectItem,
                '-'
            );
         }

         if (this.enableFace) {
             items.push({
                 text: '',
                 iconCls: 'aby-htmleditor-face',
                 handler: this.showFace,
                 scope: this
             });
         }

         if (this.enableUpload) {
             items.push({
                 xtype: 'button',
                 iconCls: 'aby-htmleditor-upload',
                 handler: this.upload,
                 scope: this
             });
         }

         if (this.enableFormat) {
             items.push(
                btn('bold'),
                btn('italic'),
                btn('underline')
            );
         }

         if (this.enableFontSize) {
             items.push(
                '-',
                btn('increasefontsize', false, this.adjustFont),
                btn('decreasefontsize', false, this.adjustFont)
            );
         }

         if (this.enableColors) {
             items.push(
                '-', {
                    itemId: 'forecolor',
                    cls: 'x-btn-icon',
                    iconCls: 'x-edit-forecolor',
                    clickEvent: 'mousedown',
                    tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
                    tabIndex: -1,
                    menu: new Ext.menu.ColorMenu({
                        allowReselect: true,
                        focus: Ext.emptyFn,
                        value: '000000',
                        plain: true,
                        listeners: {
                            scope: this,
                            select: function(cp, color) {
                                this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#' + color : color);
                                this.deferFocus();
                            }
                        },
                        clickEvent: 'mousedown'
                    })
                }, {
                    itemId: 'backcolor',
                    cls: 'x-btn-icon',
                    iconCls: 'x-edit-backcolor',
                    clickEvent: 'mousedown',
                    tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
                    tabIndex: -1,
                    menu: new Ext.menu.ColorMenu({
                        focus: Ext.emptyFn,
                        value: 'FFFFFF',
                        plain: true,
                        allowReselect: true,
                        listeners: {
                            scope: this,
                            select: function(cp, color) {
                                if (Ext.isGecko) {
                                    this.execCmd('useCSS', false);
                                    this.execCmd('hilitecolor', color);
                                    this.execCmd('useCSS', true);
                                    this.deferFocus();
                                } else {
                                    this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#' + color : color);
                                    this.deferFocus();
                                }
                            }
                        },
                        clickEvent: 'mousedown'
                    })
                }
            );
         }

         if (this.enableAlignments) {
             items.push(
                '-',
                btn('justifyleft'),
                btn('justifycenter'),
                btn('justifyright')
            );
         }

         if (!Ext.isSafari2) {
             if (this.enableLinks) {
                 items.push(
                    '-',
                    btn('createlink', false, this.createLink)
                );
             }

             if (this.enableLists) {
                 items.push(
                    '-',
                    btn('insertorderedlist'),
                    btn('insertunorderedlist')
                );
             }
             if (this.enableSourceEdit) {
                 items.push(
                    '-',
                    btn('sourceedit', true, function(btn) {
                        this.toggleSourceEdit(!this.sourceEditMode);
                    })
                );
             }
         }

         // build the toolbar
         var tb = new Ext.Toolbar({
             renderTo: this.wrap.dom.firstChild,
             items: items
         });

         if (this.hideTools) {
             this.hideTool();
         }
         if (fontSelectItem) {
             this.fontSelect = fontSelectItem.el;

             this.mon(this.fontSelect, 'change', function() {
                 var font = this.fontSelect.dom.value;
                 this.relayCmd('fontname', font);
                 this.deferFocus();
             }, this);
         }

         // stop form submits
         this.mon(tb.el, 'click', function(e) {
             e.preventDefault();
         });
         this.tb = tb;
         this.tb.doLayout();
     },
     showTool: function() {
         this.wrap.dom.firstChild.style.display = 'block';
     },
     hideTool: function() {
         this.wrap.dom.firstChild.style.display = 'none';
     },
     onDestroy: function() {
         if (this.monitorTask) {
             Ext.TaskMgr.stop(this.monitorTask);
         }
         if (this.rendered) {
             Ext.destroy(this.tb);
             var doc = this.getDoc();
             if (doc) {
                 try {
                     Ext.EventManager.removeAll(doc);
                     for (var prop in doc) {
                         delete doc[prop];
                     }
                 } catch (e) { }
             }
             if (this.wrap) {
                 this.wrap.dom.innerHTML = '';
                 this.wrap.remove();
             }
         }

         if (this.el) {
             this.el.removeAllListeners();
             this.el.remove();
         }
         if (this.faceWin) {
             this.faceWin.getEl().removeAllListeners();
             this.faceWin.getEl().remove();
         }
         if (this.uploadWin) {
             this.uploadWin.getEl().removeAllListeners();
             this.uploadWin.getEl().remove();
         }
         this.purgeListeners();
     },
     showFace: function(el) {
         var me = this;
         var win = this.faceWin;
         if (!win) {
             var tpl = (me.abyParent || "") + "/aby/resources/images/face/{0}.gif";
             var items = [], tmp;

             for (var i = 0; i < 50; i++) {
                 items.push({
                     icon: String.format(tpl, i)
                 })
             }
             win = new Ext.QuickTip({
                 autoHide: false,
                 target: el.getEl(),
                 width: 350,
                 anchor: 'top',
                 closable: true,
                 cls: 'aby-htmleditor-fasespace',
                 defaults: {
                     xtype: 'button',
                     handler: function(el) {
                         var text = String.format("<img src='{0}' />", el.icon);
                         me.insertAtCursor(text);
                         me.faceWin.hide()
                     }
                 },
                 layout: 'column',
                 items: [items]

             });
             this.faceWin = win;
         }
         win.show()
     }
	,
     upload: function(el) {
         var me = this;
         var win = this.uploadWin;
         if (!win) {
             var item = new Ext.form.FormPanel({
                 labelWidth: 50,
                 border: false,
                 fileUpload: true,
                 labelAlign: 'right',
                 items: [{
                     fieldLabel: '文 件',
                     name: 'htmleditorFile',
                     xtype: 'fileupload',
                     buttonText: '浏览',
                     width: 250,
                     focusUpload: true,
                     listeners: {
                         fileselected: function(el) {
                         if (me.url)
                             item.form.submit({
                                 url: me.url,
                                 success: me.onUploadCb,
                                 scope: me
                             });
                             me.onUpload.call(me, el);
                         }
                     }
}]
                 });
                 win = new Ext.QuickTip({
                     autoHide: false,
                     target: el.getEl(),
                     width: 350,
                     anchor: 'top',
                     form: item,
                     closable: true,
                     cls: 'aby-htmleditor-upload',
                     layout: 'fit',
                     items: [item]
                 });
                 this.uploadWin = win;
             }
             win.show()
         },
     onUploadCb: function(re, op) {

    },
     onUpload: function(el) {
            this.uploadWin.hide();
        }
     });
 
/**
 * 关闭允许关闭的tab
 * @param {} autoDestroy
 */
Ext.TabPanel.prototype.removeCanClose = function(autoDestroy)
{
	var items = [];
	this.items.each(function(item)
	{
		if(item.closable)
		{
			items.push(item);
		}
	}, this);
	Ext.each(items, function(item)
	{
		this.remove(item);
	}, this);
};
 
Ext.Window.override({
 	algin : function(al){
        var xy = this.el.getAlignToXY(this.container, al);
        this.setPagePosition(xy[0], xy[1]);
        return this;
    }
 });
 
 

/*
 * 
 * ****************************************************************************
 * 
 */

/**
 * 初始化ExtJS的部分代码
 */

Ext.BLANK_IMAGE_URL = Aby.BLANK_IMAGE_URL || Aby.BLANK_IMG_URL;
Ext.form.Field.prototype.msgTarget = "side";
Ext.QuickTips.init(true);





Ext.UpdateManager.defaults.indicatorText = '<div class="loading-indicator">加载中...</div>';

if (Ext.View) {
    Ext.View.prototype.emptyText = "";
}

if (Ext.grid.GridPanel) {
    Ext.grid.GridPanel.prototype.ddText = "{0} 选择行";
}

if (Ext.TabPanelItem) {
    Ext.TabPanelItem.prototype.closeText = "关闭";
}

if (Ext.form.Field) {
    Ext.form.Field.prototype.invalidText = "输入值非法";
}

Date.monthNames = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];

Date.dayNames = ["日", "一", "二", "三", "四", "五", "六"];

if (Ext.MessageBox) {
    Ext.MessageBox.buttonText =
	{
	    ok: "确定",
	    cancel: "取消",
	    yes: "是",
	    no: "否"
	};
}

if (Ext.util.Format) {
    Ext.util.Format.date = function (v, format) {
        if (!v) return "";
        if (!(v instanceof Date)) v = new Date(Date.parse(v));
        return v.dateFormat(format || "y年m月d日");
    };
}

if (Ext.DatePicker) {
    Ext.apply(Ext.DatePicker.prototype,
	{
	    todayText: "今天",
	    minText: "日期在最小日期之前",
	    maxText: "日期在最大日期之后",
	    disabledDaysText: "",
	    disabledDatesText: "",
	    monthNames: Date.monthNames,
	    dayNames: Date.dayNames,
	    nextText: '下月 (Control+Right)',
	    prevText: '上月 (Control+Left)',
	    monthYearText: '选择一个月 (Control+Up/Down 来改变年)',
	    todayTip: "{0} (空格键选择)",
	    format: "y年m月d日",
	    okText: "确定",
	    cancelText: "取消"
	});
}

if (Ext.PagingToolbar) {
    Ext.apply(Ext.PagingToolbar.prototype,
	{
	    beforePageText: "页",
	    afterPageText: "页共 {0} 页",
	    firstText: "第一页",
	    prevText: "前一页",
	    nextText: "下一页",
	    lastText: "最后页",
	    refreshText: "刷新",
	    displayMsg: "显示 {0} - {1}，共 {2} 条",
	    emptyMsg: '没有数据需要显示'
	});
}

if (Ext.form.TextField) {
    Ext.apply(Ext.form.TextField.prototype,
	{
	    minLengthText: "该输入项的最小长度是 {0}",
	    maxLengthText: "该输入项的最大长度是 {0}",
	    blankText: "不能为空！",
	    regexText: "",
	    emptyText: null
	});
}

if (Ext.form.NumberField) {
    Ext.apply(Ext.form.NumberField.prototype,
	{
	    minText: "该输入项的最小值是 {0}",
	    maxText: "该输入项的最大值是 {0}",
	    nanText: "{0} 不是有效数值"
	});
}

if (Ext.form.DateField) {
    Ext.apply(Ext.form.DateField.prototype,
	{
	    disabledDaysText: "禁用",
	    disabledDatesText: "禁用",
	    minText: "该输入项的日期必须在 {0} 之后",
	    maxText: "该输入项的日期必须在 {0} 之前",
	    invalidText: "{0} 是无效的日期 - 必须符合格式： {1}",
	    format: "y年m月d日"
	});
}

if (Ext.form.ComboBox) {
    Ext.apply(Ext.form.ComboBox.prototype,
	{
	    loadingText: "加载...",
	    valueNotFoundText: undefined
	});
}

if (Ext.form.VTypes) {
    Ext.apply(Ext.form.VTypes,
	{
	    emailText: '该输入项必须是电子邮件地址，格式如： "user@example.com"',
	    urlText: '该输入项必须是URL地址，格式如： "http:/' + '/www.example.com"',
	    alphaText: '该输入项只能包含字符和_',
	    alphanumText: '该输入项只能包含字符,数字和_'
	});
}

if (Ext.grid.GridView) {
    Ext.apply(Ext.grid.GridView.prototype,
	{
	    sortAscText: "正序",
	    sortDescText: "逆序",
	    lockText: "锁列",
	    unlockText: "解锁列",
	    columnsText: "列"
	});
}

if (Ext.grid.PropertyColumnModel) {
    Ext.apply(Ext.grid.PropertyColumnModel.prototype,
	{
	    nameText: "名称",
	    valueText: "值",
	    dateFormat: "y年m月d日"
	});
}

if (Ext.layout.BorderLayout && Ext.layout.BorderLayout.SplitRegion) {
    Ext.apply(Ext.layout.BorderLayout.SplitRegion.prototype,
	{
	    splitTip: "拖动来改变尺寸.",
	    collapsibleSplitTip: "拖动来改变尺寸. 双击隐藏."
	});
}